package com.xzit.rcpyxt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xzit.rcpyxt.constant.Constant;
import com.xzit.rcpyxt.constant.MessageCode;
import com.xzit.rcpyxt.dto.*;
import com.xzit.rcpyxt.entity.Class;
import com.xzit.rcpyxt.entity.Teacher;
import com.xzit.rcpyxt.exceptions.CustomeException;
import com.xzit.rcpyxt.mapper.ClassMapper;
import com.xzit.rcpyxt.mapper.StudentMapper;
import com.xzit.rcpyxt.mapper.TeacherMapper;
import com.xzit.rcpyxt.service.TeacherService;
import com.xzit.rcpyxt.utils.HttpCommon;
import com.xzit.rcpyxt.utils.PageUtil;
import com.xzit.rcpyxt.utils.TOTPUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

@Service
public class TeacherServiceImpl implements TeacherService {

    private final static Logger logger = LogManager.getLogger(TeacherServiceImpl.class);

    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ClassMapper classMapper;

    @Override
    public PageUtil findByTeacherList (TeacherListRequestDto teacherDto) {
        int page = teacherDto.getPage();
        int pageSize = teacherDto.getPageSize();
        teacherDto.setPage(page - 1);
        teacherDto.setPageSize(page * pageSize);
        List<Teacher> teachers = teacherMapper.selectByTeacherList(teacherDto);
        int totalElements = teacherMapper.countByTeacherList(teacherDto);
        return new PageUtil(page, pageSize, totalElements, teachers);
    }

    @Override
    public JSONObject bindUserInfo(BindUserDto bindUserDto) {
        if (StringUtils.isBlank(bindUserDto.getCode())){
            throw new CustomeException(MessageCode.PARAME_NOT_NULL_ERROR.getCode(), "code不能为空！");
        }
        bindUserDto.setOpenId(getOpendId(bindUserDto));
        int success = 0;
        JSONObject data = null;
        switch (bindUserDto.getType()) {
            case 0:
                success = teacherMapper.updateByTeacherOpenId(bindUserDto);
                if (success > 0) {
                    data = JSON.parseObject(JSON.toJSONString(teacherMapper.selectByTeacherUserInfo(bindUserDto.getId())));
                }
                break;
            case 1:
                success = studentMapper.updateByStudentOpenId(bindUserDto);
                if (success > 0) {
                    data = JSON.parseObject(JSON.toJSONString(studentMapper.selectByStudentUserInfo(bindUserDto.getId())));
                    Class classId = classMapper.selectByPrimaryKey(data.getInteger("classId"));
                    data.put("className", classId != null ? classId.getName() : "");
                }
                break;
            default:
                throw new CustomeException(MessageCode.PARAME_ERROR.getCode(), "绑定类型不存在！");
        }
        if (success > 0) {
            if (data == null) throw new CustomeException(MessageCode.BING_USER_ERROR.getCode(), "用户不存在！");
            data.put("type", bindUserDto.getType());
            data.put("isTeacher", bindUserDto.getType() == 0 ? true : false);
            long time = System.currentTimeMillis();
            data.put("token", TOTPUtil.generateMyTOTP(data.getString("openId") + time, TOTPUtil.SECRET_KEY) + "|" + time);
            return data;
        }
        throw new CustomeException(MessageCode.BING_USER_ERROR.getCode(), "用户不存在！");
    }

    @Override
    public JSONObject checkUserIsBing(BindUserDto bindUserDto) {
        if (StringUtils.isBlank(bindUserDto.getCode())){
            throw new CustomeException(MessageCode.PARAME_NOT_NULL_ERROR.getCode(), "code不能为空！");
        }
        String opendId = getOpendId(bindUserDto);
        JSONObject data = null;
        switch (bindUserDto.getType()) {
            case 0:
                data = JSON.parseObject(JSON.toJSONString(teacherMapper.selectByTeacherIsBingUser(opendId)));
                break;
            case 1:
                data = JSON.parseObject(JSON.toJSONString(studentMapper.selectByStudentIsBingUser(opendId)));
                Class classId = classMapper.selectByPrimaryKey(data.getInteger("classId"));
                data.put("className", classId != null ? classId.getName() : "");
                break;
            default:
                throw new CustomeException(MessageCode.PARAME_ERROR.getCode(), "绑定类型不存在！");
        }
        if (data == null) throw new CustomeException(MessageCode.USER_AUTH_ERROR);
        data.put("type", bindUserDto.getType());
        data.put("isTeacher", bindUserDto.getType() == 0 ? true : false);
        long time = System.currentTimeMillis();
        data.put("token", TOTPUtil.generateMyTOTP(opendId + time, TOTPUtil.SECRET_KEY) + "|" + time);
        return data;
    }

    /**
     * 获取openId
     * @param bindUserDto
     * @return
     */
    private String getOpendId (BindUserDto bindUserDto) {
        String openId = null;
        ResultModel common = null;
        String openIdUrl = String.format(Constant.getOpenIdUrl, Constant.appId, Constant.appSecret, bindUserDto.getCode());
        try {
            common = HttpCommon.get(openIdUrl);
            logger.info("bindUserInfo httpCommon " + JSON.toJSONString(common));
            if (common.getCode() != 200) {
                throw new CustomeException(MessageCode.NETWORK_ERROR);
            }
            JSONObject date = JSON.parseObject(common.getMessage());
            Integer errcode = date.getInteger("errcode");
            if (errcode != null) {
                if (errcode == MessageCode.WX_CODE_ERROR.getCode()) {
                    throw new CustomeException(MessageCode.WX_CODE_ERROR);
                } else if (errcode == MessageCode.WX_CODE_APPID_ERROR.getCode()) {
                    throw new CustomeException(MessageCode.WX_CODE_APPID_ERROR);
                } else {
                    throw new CustomeException(MessageCode.SYSTEM_ERROR.getCode(), date.getString("errmsg"));
                }
            }
            openId = date.getString("openid");
        } catch (IOException e) {
            throw new CustomeException(MessageCode.SYSTEM_ERROR.getCode(), "获取openid失败！");
        }
        return openId;
    }

}